home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / video / seqgrab / vlan.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  10.7 KB  |  474 lines

  1. /*
  2.  * Copyright (C) 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*
  18.     vlan.c - Routines to help talk to VLAN network.
  19.     
  20.     Tim Heidmann
  21.     Created     March  1, 1993
  22.     Last Edit   Oct   22, 1993
  23.     Add vlan_Send (send-only) and vlan_Recv (poll for ascii/bin messages).
  24.     Add minimal timestamping.
  25. */
  26.  
  27. #include <stdio.h>
  28. #include <fcntl.h>
  29. #include <termio.h>
  30. #include "vlan.h"
  31.  
  32. #define VLAN_CMD_NAP 5
  33. #define VLAN_CMD_TIMEOUT 15
  34.  
  35. int vlan_sending = TRUE;
  36. int vlan_receiving = TRUE;
  37. int vlan_debug = FALSE;
  38. int vlan_errno;
  39. int vlan_f;
  40. char vlan_port[256] = "/dev/ttyd2";
  41. char vlan_neatTC_buf[64];
  42. int vlan_timeout = -1;
  43. struct timeval vlan_msg_stamp;
  44.  
  45. int vlan_SetTimeout(int, int);
  46.  
  47. int
  48. vlan_InitPort(char *vlan_port)
  49. {
  50.     struct termio term;
  51.  
  52.     if (vlan_sending) {
  53.     if ((vlan_f = open(vlan_port, O_RDWR)) < 0) {
  54.         vlan_errno = VLAN_CANT_OPEN;
  55.         return -1;
  56.     }
  57.     }
  58.  
  59.     if (ioctl(vlan_f, TCGETA, &term) == -1) {
  60.     vlan_errno = VLAN_TCGETA;
  61.         return -1;
  62.     }
  63.  
  64.     /* change the modes */
  65.     term.c_iflag = IGNBRK;
  66.     term.c_oflag = 0;
  67.     term.c_lflag = 0;
  68.     term.c_cflag = B9600 | CS8 | CREAD;
  69.     term.c_cc[VMIN] = 1;
  70.     term.c_cc[VTIME] = 0;
  71.  
  72.     if (ioctl(vlan_f, TCSETA, &term) == -1) {
  73.     vlan_errno = VLAN_TCSETA;
  74.         return -1;
  75.     }
  76.  
  77.     return 0;
  78. }
  79.  
  80. char *
  81. vlan_SendCmd(char c[])
  82. {
  83.     int iChar, timedOut;
  84.     char vlan_command[256];
  85.     static char vlan_response[256];
  86.     char *resp;
  87.  
  88.     /* Flush the input buffer */
  89.     if (vlan_receiving) {
  90.     /* Set up for immediate return */
  91.     if (vlan_SetTimeout(0, 0) < 0) return NULL;
  92.     while (read(vlan_f,resp,1) > 0) ;
  93.     }
  94.  
  95.     /* Send the desired command */
  96.     if (vlan_debug)
  97.     fprintf(stdout, "--IRIS: %s\n", c);
  98.     if (vlan_sending) {
  99.     for (iChar = 0; c[iChar] != '\0'; iChar++)
  100.         vlan_command[iChar] = c[iChar];
  101.     vlan_command[iChar++] = '\r';
  102.     write(vlan_f, vlan_command, iChar);
  103. /*
  104.     sginap(VLAN_CMD_NAP);
  105. */
  106.     }
  107.  
  108.     /* Read the VLAN response */
  109.     if (vlan_receiving)
  110.     /* Set up for max allowed response time */
  111.     if (vlan_SetTimeout(0, VLAN_CMD_TIMEOUT) < 0) return NULL;
  112.     timedOut = FALSE;
  113.     for (resp = vlan_response; ; resp++) {
  114.         if (read(vlan_f,resp,1) <= 0) {
  115.         /* Timeout */
  116.         *resp = '\0';
  117.         timedOut = TRUE;
  118.         break;
  119.         }
  120.         if (*resp == '\r') {
  121.         /* Carriage return signals end of response */
  122.         *resp = '\0';
  123.         break;
  124.         }
  125.     }
  126.  
  127.     if (vlan_debug)
  128.     fprintf(stdout, "  VLAN: %s%s\n",
  129.         vlan_response, timedOut ? "*** TIMEOUT ***" : "");
  130.     
  131.     return timedOut ? NULL : vlan_response;
  132. }
  133.  
  134. int
  135. vlan_Coincidence(int ds, char *ch) {
  136.     int val;
  137.     char blah[1];
  138.     fd_set fdset;
  139.     struct timeval timeout;
  140.  
  141.     if (!vlan_receiving) 
  142.       return 0;
  143.  
  144. /***
  145.     FD_ZERO(&fdset);
  146.     FD_SET(vlan_f, &fdset);
  147.     timeout.tv_sec = 30;
  148.     timeout.tv_usec = 0;
  149.     val = select(1, fdset, 0, 0, 0);
  150.     printf("val returned from select = %d\n", val);
  151. ***/
  152.     
  153.     /* Set maximum wait time (1/10th secs) */
  154.     if (vlan_SetTimeout(1, ds) < 0) return -1;
  155.  
  156.      /* Wait here for a character  */
  157.      val = read(vlan_f, blah, 1);
  158.     if (val < 0) {
  159.     vlan_errno = VLAN_READ_COINCIDENCE;
  160.     return -1;
  161.     } 
  162.     else if (val == 0) {
  163.     vlan_errno = VLAN_TIMEOUT;
  164.     return -1;
  165.     } 
  166.     else 
  167.     {      
  168.         *ch = blah[0];
  169.     return 0;
  170.     }
  171. }
  172.  
  173.  
  174. int
  175. vlan_SetTimeout(int min, int ds)
  176. {
  177.     struct termio term;
  178.  
  179.     if (!vlan_receiving) return 0;
  180.  
  181.     if (ds < 0 || ds > 255) {
  182.         vlan_errno = VLAN_BAD_TIMEOUT;
  183.         return -1;
  184.     }
  185.  
  186.     if (ioctl(vlan_f, TCGETA, &term) == -1) {
  187.     vlan_errno = VLAN_TCGETA;
  188.         return -1;
  189.     }
  190.  
  191.     /* change the MIN/TIME values
  192.      * (assume still setup for non-canonic processing)
  193.      */
  194.     term.c_cc[VMIN] = min;
  195.     term.c_cc[VTIME] = vlan_timeout = ds;
  196.  
  197.     if (ioctl(vlan_f, TCSETA, &term) == -1) {
  198.     vlan_errno = VLAN_TCSETA;
  199.         return -1;
  200.     }
  201.  
  202.     return 0;
  203. }
  204.  
  205.  
  206.  
  207. #define FPS     30
  208. #define FPM   1800
  209. #define FPH 108000
  210. static char vlan_tcBuf[32];
  211.  
  212. char *vlan_FtoTC(int iFrame) {
  213.     int h, m, s;
  214.  
  215.     if (iFrame < 0)
  216.     vlan_tcBuf[0] = '\0';
  217.  
  218.     else {
  219.     h = iFrame / FPH;
  220.     iFrame -= h * FPH;
  221.     m = iFrame / FPM;
  222.     iFrame -= m * FPM;
  223.     s = iFrame / FPS;
  224.     iFrame -= s * FPS;
  225.     sprintf(vlan_tcBuf, "%02d:%02d:%02d:%02d", h, m, s, iFrame);
  226.     }
  227.  
  228.     return vlan_tcBuf;
  229. }
  230.  
  231. int vlan_TCtoF(char *tc) {
  232.     int h, m, s, f;
  233.     char *neat_tc;
  234.  
  235.     neat_tc = vlan_neatTC(tc);
  236.     if (sscanf(neat_tc, "%2d%2d%2d%2d", &h, &m, &s, &f) != 4) {
  237.     vlan_errno = VLAN_PARSE_TIMECODE;
  238.     return -1;
  239.     }
  240.  
  241.     return (h*FPH + m*FPM + s*FPS + f);
  242. }
  243.  
  244. char *vlan_neatTC(char *tc) {
  245.     char *np, tmpBuf[64];
  246.     int bufLen;
  247.  
  248.     /* Remove all but numerics. */
  249.     for (np = tmpBuf; *tc != '\0'; tc++)
  250.     if (*tc >= '0' && *tc <= '9') {
  251.         *np = *tc;
  252.         np++;
  253.     }
  254.     *np = '\0';
  255.  
  256.     /* Return empty string if no numerics at all.
  257.      * Otherwise, truncate to 8 characters (hhmmssff) or pad with 0's
  258.      */
  259.     if ((bufLen = strlen(tmpBuf)) <= 0)
  260.     vlan_neatTC_buf[0] = '\0';
  261.     else if (bufLen > 8)
  262.     strcpy(vlan_neatTC_buf, tmpBuf + bufLen - 8);
  263.     else {
  264.     strcpy(vlan_neatTC_buf, "00000000");
  265.     strcpy(vlan_neatTC_buf + 8 - bufLen, tmpBuf);
  266.     }
  267.     
  268.     return vlan_neatTC_buf;
  269. }
  270.  
  271.  
  272. void
  273. vlan_perror(char *str) {
  274.     char buf[256];
  275.  
  276.     switch (vlan_errno) {
  277.     case VLAN_CANT_OPEN:
  278.     sprintf(buf, "%s: Open VLAN port", str);
  279.     perror(buf);
  280.     break;
  281.     case VLAN_TCGETA:
  282.     sprintf(buf, "%s: Get VLAN serial attributes", str);
  283.     perror(buf);
  284.     break;
  285.     case VLAN_TCSETA:
  286.     sprintf(buf, "%s: Set VLAN serial attributes", str);
  287.     perror(buf);
  288.     break;
  289.     case VLAN_PARSE_TIMECODE:
  290.     fprintf(stderr, "%s: Can't parse VLAN timecode string\n", str);
  291.     break;
  292.     case VLAN_BAD_TIMEOUT:
  293.     fprintf(stderr, "%s: Bad VLAN timeout specification\n", str);
  294.     break;
  295.     case VLAN_READ_COINCIDENCE:
  296.     sprintf(buf, "%s: Read VLAN coincidence character", str);
  297.     perror(buf);
  298.     break;
  299.     case VLAN_TIMEOUT:
  300.     fprintf(stderr, "%s: VLAN timeout\n", str);
  301.     break;
  302.     case VLAN_CAPTURE_DEAD:
  303.     fprintf(stderr, "%s: VLAN continuous capture timeout\n", str);
  304.     break;
  305.     default:
  306.     fprintf(stderr, "%s: VLAN error\n", str);
  307.     break;
  308.     }
  309. }
  310.  
  311.  
  312.  
  313. void
  314. vlan_Send(char c[])
  315. {
  316.     int iChar, timedOut;
  317.     char vlan_command[256];
  318.     static char vlan_response[256];
  319.     char *resp;
  320.  
  321.     /* Flush the input buffer */
  322.     if (vlan_receiving) {
  323.     /* Set up for immediate return */
  324.     vlan_SetTimeout(0, 0);
  325.     while (read(vlan_f,resp,1) > 0) ;
  326.     }
  327.  
  328.     /* Send the desired command */
  329.     if (vlan_debug)
  330.     fprintf(stdout, "--IRIS: %s\n", c);
  331.     if (vlan_sending) {
  332.     for (iChar = 0; c[iChar] != '\0'; iChar++)
  333.         vlan_command[iChar] = c[iChar];
  334.     vlan_command[iChar++] = '\r';
  335.     write(vlan_f, vlan_command, iChar);
  336.     }
  337. }
  338.  
  339.  
  340. #define VLAN_RECVBUF_LEN 512
  341. unsigned char vlan_recvBuf[VLAN_RECVBUF_LEN];
  342. int vlan_recvBuf_start = 0, vlan_recvBuf_end = 0;
  343. int charCnt = 0;
  344. enum {vlan_recv_start, vlan_recv_ascii, vlan_recv_esc, vlan_recv_flush}
  345.     vlan_recv_state;
  346.  
  347. int
  348. vlan_Recv(char **c, vlan_esc_struct **e, struct timeval *ts) {
  349.     int this_start, i, n, j;
  350.  
  351.     if (vlan_SetTimeout(0, 0) < 0) return -1;
  352.     if ((n = read(vlan_f, vlan_recvBuf + vlan_recvBuf_end,
  353.     VLAN_RECVBUF_LEN - vlan_recvBuf_end)) < 0) return -1;
  354.     charCnt += n;
  355.     this_start = vlan_recvBuf_end;
  356.     vlan_recvBuf_end += n;
  357.     
  358.     for (;;)
  359.     switch (vlan_recv_state) {
  360.     case vlan_recv_start:
  361.         /* Move buffer contents to head of buffer; check for ASCII/bin */
  362.         if (vlan_recvBuf_start > 0) {
  363.         for (i = 0; i < vlan_recvBuf_end - vlan_recvBuf_start; i++)
  364.             vlan_recvBuf[i] = vlan_recvBuf[i+vlan_recvBuf_start];
  365.         vlan_recvBuf_end -= vlan_recvBuf_start;
  366.         vlan_recvBuf_start = 0;
  367.         }
  368.  
  369.         if (vlan_recvBuf_end == vlan_recvBuf_start)
  370.         /* Nothing read yet */
  371.         return 0;
  372.  
  373.         else {
  374.         gettimeofday(&vlan_msg_stamp, NULL);
  375.         vlan_msg_stamp.tv_usec -= 1000 * n;
  376.         this_start = vlan_recv_start;
  377.         if (vlan_recvBuf[vlan_recvBuf_start] == 0x1b)
  378.             /* Escape message */
  379.             vlan_recv_state = vlan_recv_esc;
  380.         else if ((vlan_recvBuf[vlan_recvBuf_start] >= 32 &&
  381.             vlan_recvBuf[vlan_recvBuf_start] <= 127) ||
  382.             vlan_recvBuf[vlan_recvBuf_start] == '\r')
  383.             /* Ascii */
  384.             vlan_recv_state = vlan_recv_ascii;
  385.         else
  386.             /* Random binary stuff - flush it */
  387.             vlan_recv_state = vlan_recv_flush;
  388.         }
  389.         break;
  390.  
  391.  
  392.     case vlan_recv_ascii:
  393.         for (i=this_start; i<vlan_recvBuf_end; i++) {
  394.         if (vlan_recvBuf[i] == '\r') {
  395.             /* End of ascii message */
  396.             *c = vlan_recvBuf + vlan_recvBuf_start;
  397.             vlan_recvBuf[i] = '\0';
  398.             if (ts != NULL) *ts = vlan_msg_stamp;
  399. if (vlan_debug)
  400.     fprintf(stdout, "ASCII: %s (%d bytes remain)\n", *c, vlan_recvBuf_end-i-1);
  401.             vlan_recvBuf_start = i + 1;
  402.             vlan_recv_state = vlan_recv_start;
  403.             break;
  404.         
  405.         } else if (vlan_recvBuf[vlan_recvBuf_start] < 32 &&
  406.             vlan_recvBuf[vlan_recvBuf_start] > 127) {
  407.             /* Non-ascii value detected in message */
  408.             vlan_recv_state = vlan_recv_flush;
  409.             break;
  410.         }
  411.         }
  412.         if (vlan_recv_state == vlan_recv_start) return 1;
  413.         else if (vlan_recv_state == vlan_recv_flush) break;
  414.         else
  415. /*
  416.         return 0;
  417. */
  418. if (vlan_recvBuf_start == vlan_recvBuf_end) {
  419.     return 0;
  420. } else {
  421.     return 3;
  422. }
  423.  
  424.  
  425.     case vlan_recv_esc:
  426.         for (i=this_start; i<vlan_recvBuf_end; i++) {
  427.         if (vlan_recvBuf[i] == '\r') {
  428.             /* End of escape message */
  429.             *e = (vlan_esc_struct *) vlan_recvBuf + vlan_recvBuf_start;
  430. if (vlan_debug) {
  431.     fprintf(stdout, "ESC: ");
  432.     for (j = vlan_recvBuf_start; j <= i; j++) {
  433.     if ((j % 16) == 15) fprintf(stdout,"\n     ");
  434.     fprintf(stdout, "0x%02x ", vlan_recvBuf[j]);
  435.     }
  436.     fprintf(stdout, "\n");
  437. }
  438.             if (ts != NULL) *ts = vlan_msg_stamp;
  439.             vlan_recvBuf_start = i + 1;
  440.             vlan_recv_state = vlan_recv_start;
  441.             break;
  442.         }
  443.         }
  444.         if (vlan_recv_state == vlan_recv_start) return 2;
  445.         else
  446. /*
  447.         return 0;
  448. */
  449. if (vlan_recvBuf_start == vlan_recvBuf_end) {
  450.     return 0;
  451. } else {
  452.     return 3;
  453. }
  454.  
  455.  
  456.     case vlan_recv_flush:
  457.         /* Look for a CR */
  458.         for (i = vlan_recvBuf_start; i < vlan_recvBuf_end; i++)
  459.         if (vlan_recvBuf[i] == '\r') {
  460.             vlan_recvBuf_start = i + 1;
  461.             vlan_recv_state = vlan_recv_start;
  462.             break;
  463.         }
  464.  
  465.         if (vlan_recv_state == vlan_recv_flush) {
  466.         /* No CR found in this batch. Return */
  467.         vlan_recvBuf_start = vlan_recvBuf_end = 0;
  468.         return 0;
  469.         }
  470.         break;
  471.     }
  472. }
  473.  
  474.